//role.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { In, Repository, Like } from 'typeorm';
import { CreateRoleDto } from './dto/create-role.dto';
import { FindAllDto, UpdateRoleDto } from './dto/update-role.dto';
import { NewsPaginationParams } from '../agent_manag/dto/update-agent_manag.dto';
import { Role } from './entities/role.entity';
import { Permission } from '../permission/entities/permission.entity';
import { ApiException } from 'src/common/filter/http-exception/api.exception';
import { ApiErrorCode } from 'src/common/enums/api-error-code.enum';
import { CacheService } from 'src/cache/cache.service';
import { format } from 'date-fns';
@Injectable()
export class RoleService {
  constructor(
    @InjectRepository(Role)
    private roleRepository: Repository<Role>,
    @InjectRepository(Permission)
    private permissionRepository: Repository<Permission>,
    private cacheService: CacheService,
  ) {}
  async create(createRoleDto: CreateRoleDto) {
    //查询传入数组permissionIds的全部permission实体
    const permissions = await this.permissionRepository.find({
      where: {
        id: In(createRoleDto.permissionIds),
      },
    });
    const name = createRoleDto.name;
    const existRole = await this.roleRepository.findOne({
      where: { name },
    });

    if (existRole)
      throw new ApiException('角色已存在', ApiErrorCode.ROLE_EXIST);
    await this.roleRepository.save({ permissions, name });
    return '角色创建成功';
  }

  async findUserRoles(roleIds: number[]) {
    const arr: string[] = [];
    for (const roleId of roleIds) {
      const name = await this.cacheService.get<string>(`role_${roleId}_name`);
      if (name) {
        arr.push(name);
      }
    }
    //如果缓存中有全部的角色名称，则直接返回
    if (arr.length === roleIds.length) {
      return arr;
    }

    const roles = await this.roleRepository.find({
      where: {
        id: In(roleIds),
      },
    });
    if (!roles) return [];
    for (const role of roles) {
      await this.cacheService.set(
        `role_${role.id}_name`,
        role.name,
        60 * 60 * 24,
      );
    }
    return roles.flatMap((role) => role.name);
  }

  async findAll(data: NewsPaginationParams & FindAllDto) {
    const whereCondition = data.name ? { name: Like(`%${data.name}%`) } : {};
    const roles = await this.roleRepository.findAndCount({
      relations: ['permissions'],
      where: whereCondition,
      skip: (data.current - 1) * data.size,
      take: data.size,
      select: ['id', 'name', 'permissions', 'createTime'],
      order: {
        id: 'DESC',
      },
    });
    return {
      records: roles[0].map((role) => {
        return {
          id: role.id,
          name: role.name,
          permissions: role.permissions.map((permission) => {
            return {
              id: permission.id,
              name: permission.name,
            };
          }),
          createTime: format(role.createTime, 'yyyy-MM-dd HH:mm:ss'), //格式化时间
        };
      }),
      total: roles[1],
      current: data.current,
      size: data.size,
    };
  }

  findOne(id: number) {
    if (!id) throw new ApiException('角色id不能为空', ApiErrorCode.USER_NOTEXIST);
    return this.roleRepository.findOne({
      where: { id },
      relations: ['permissions'],
    });
  }

  async update(id: number, updateRoleDto: UpdateRoleDto) {
    const { permissionIds, ...rest } = updateRoleDto;
    const role = await this.roleRepository.findOne({ where: { id } });
    if (!role) throw new ApiException('角色不存在', ApiErrorCode.USER_NOTEXIST);
    if (permissionIds && permissionIds.length > 0) {
      const permissions = await this.permissionRepository.find({
        where: {
          id: In(permissionIds),
        },
      });
      role.permissions = permissions;
    }
    Object.assign(role, rest);
    try {
      await this.roleRepository.save(role);
      return '角色更新成功';
    } catch (error) {
      console.log(error);
      return new ApiException('角色更新失败', ApiErrorCode.USER_NOTEXIST);
    }
  }

  async remove(id: number) {
    const role = await this.roleRepository.findOne({ where: { id } });
    if (!role) throw new ApiException('角色不存在', ApiErrorCode.USER_NOTEXIST);
    return this.roleRepository.delete(id);
  }
}
